import java.io.*;
import java.util.Vector;

public class peerProcess {

    static int no_of_peers;
    static PeerInfo[] peerinfo;
    static String currentPeerId;
    static int no_of_pieces;
    static long optimisticUnchokeInterval;
    static long peferredNeighborTime;
    static boolean fileMerging;
    
    static int peerID;
    static ConfigReader Common_cfg = new ConfigReader();
    static ConfigReader peerinfo_cfg = new ConfigReader();
   // static peer_cfg peer_cfgReader=new peer_cfg();
    public static BufferedWriter writer;

    public static void main(String[] args) throws IOException  {
    	// check to make sure that the user supplied the peer ID
		if(args.length < 1)
		{
			System.out.println("You must provide the peer ID as the command line parameter!");
			System.exit(0);
		}
		
		peerID = Integer.parseInt(args[0]);
		System.out.println("PeerID: " + peerID);
		
		ConfigReader reader = new ConfigReader();
		FileChunker chunker = new FileChunker(peerID);
		Logger log = new Logger(peerID);
		Packet packet = new Packet(peerID);
		
		reader.readCommon();
		reader.readPeerInfo();
	
		System.out.println(reader.numPreferredNeighbors);
		System.out.println(reader.unchokingInt);
		System.out.println(reader.optimisticUnchokingInt);
		System.out.println(reader.fileName);
		System.out.println(reader.fileSize);
		System.out.println(reader.pieceSize);
		System.out.println();
		
		for(int i = 0; i< reader.numPeers; i++)
		{
			System.out.println("Peer " + i + ":");
			System.out.println("PeerID: " + reader.peerID[i]);
			System.out.println("HostName: " + reader.hostName[i]);
			System.out.println("ListeningPort: " + reader.listeningPort[i]);
			System.out.println("HasFileOrNot: " + reader.hasFileOrNot[i]);
			System.out.println();
		}	
		
		chunker.chunkFile(reader.fileName, reader.fileSize, reader.pieceSize);
	
		chunker.recreateFile(reader.fileName, reader.fileSize, reader.pieceSize);
		
		int[] PNList = new int[3];
		
		PNList[0] = 1002;
		PNList[1] = 1003;
		PNList[2] = 1004;
		
		log.tcpConnectToLog(1002);
		log.tcpConnectFromLog(1003);
		log.changePNLog(PNList);
		log.changeOUNLog(1002);
		log.unchokingLog(1002);
		log.chokingLog(1002);
		log.haveMessageLog(1002, 5);
		log.interestedMessageLog(1002);
		log.notInterestedMessageLog(1002);
		log.downloadPieceLog(1002, 5);
		log.completeDownloadLog();
		
		// close the BufferedWriter
		writer.close();

		packet.createHandshakePacket();
		packet.createChokePacket();
		
    	
    	// TODO code application logic here
        currentPeerId = args[0];
        optimisticUnchokeInterval = 0;
        peferredNeighborTime = 0;
        
        fileMerging = false;
        
        //Common_cfg.LoadSettings();
        //peerinfo_cfg.LoadSettings();
        Common_cfg.readCommon();
        peerinfo_cfg.readPeerInfo();
	
        try {
         	  
            if ((Common_cfg.fileSize % Common_cfg.pieceSize) == 0)
                no_of_pieces = Common_cfg.fileSize / Common_cfg.pieceSize;
            else
                no_of_pieces = (Common_cfg.fileSize / Common_cfg.pieceSize)+1;
                    
            //no_of_peers = peerinfo_cfg.peerID.size();
            no_of_peers = peerinfo_cfg.numPeers;
            
            java.net.ServerSocket welcomeSocket = new java.net.ServerSocket();
           
            boolean filePresent;
       //     peer_cfg peer_cfg=new peer_cfg();
            
            peer_cfg.LoadSettings();
           // System.out.println(peer_cfg.isPresent.elementAt(getPieceIndex(currentPeerId)));
            
            if (peer_cfg.isPresent.elementAt(getPieceIndex(currentPeerId)) == 1) {
                filePresent = true;
            } else {
                filePresent = false;
            }
              
            MainServer tcpserver = new MainServer(filePresent);
           
            welcomeSocket = tcpserver.Server();
            
            ClientThread ct;
            peerinfo = new PeerInfo[no_of_peers];
         
            String initialBitfield = "";
            int piece_count = no_of_pieces;
            for (int i = 0; i < piece_count; i++) {

                initialBitfield += "0";
            }
            
           
            for (int i = 0; i < no_of_peers; i++) {
                peerinfo[i] = new PeerInfo(peer_cfg.peerID.elementAt(i), new java.net.Socket(), initialBitfield, 0);
               
                if (!peer_cfg.peerID.elementAt(i).endsWith(currentPeerId)) {    // Check for current peer
                	 System.out.println("i am SERVER ");  
                    ct = new ClientThread(peer_cfg.peerID.elementAt(i));
                    Thread t = new Thread(ct);
                    t.start();
                }

                Thread t_server = new Thread(new TCPServer(welcomeSocket));
                System.out.println("starting tcp server");
                t_server.start();
                
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    public static int getPieceIndex(String SearchThis) {
        for (int i = 0; i < no_of_peers; i++) {
            if (peer_cfg.peerID.get(i).endsWith(SearchThis)) {
                return i;
            }
        }
        return -1;
    }
}

class ClientThread implements Runnable {

    TCPClient tc;

    public ClientThread(String PeerId) {
        tc = new TCPClient(PeerId);
        System.out.println("getting here");
    }

    public void run() {
    	
        tc.Client();
    }
}

